﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zcu.PanelComposer.Interfaces;
using System.ComponentModel.Composition;
using Caliburn.Micro;
using Zcu.PanelComposer.ViewModels.Events;
using System.Reflection;
using Zcu.PanelComposer.Models.Model;

namespace Zcu.PanelComposer.ViewModels
{
    /// <summary>
    /// ViewModel hlavniho okna.
    /// </summary>
    [Export(typeof(IShell))]
    public class ShellViewModel : Conductor<IModule>.Collection.OneActive, IShell, IHandle<NavigateEvent>, IHandle<ActiveSolutionEvent>, IHandle<BusyEvent>
    {
        #region Fields

        /// <summary>
        /// Logovani.
        /// </summary>
        private ILog _log = LogManager.GetLog(typeof(ShellViewModel));

        private Solution _SelectedSolution;
        private bool _isBusy;
        private string _busyIndicatorText;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the version.
        /// </summary>
        public string Version 
        {
            get 
            {  
                Version version = Assembly.GetExecutingAssembly().GetName().Version;
                return string.Format("Version: {0}.{1}.{2} (rev {3})",
                    version.Major, version.Minor, version.Build, version.Revision); }
        }

        /// <summary>
        /// Gets the menu items.
        /// </summary>
        public IObservableCollection<IModule> MenuItems { private set; get; }

        /// <summary>
        /// Gets the event aggregator.
        /// </summary>
        [Import]
        public IEventAggregator EventAggregator { get; private set; }

        /// <summary>
        /// Gets or sets the selected solution.
        /// </summary>
        /// <value>
        /// The selected solution.
        /// </value>
        public Solution SelectedSolution
        {
            get { return _SelectedSolution; }
            set
            {
                if (_SelectedSolution != value) _SelectedSolution = value;
                NotifyOfPropertyChange(() => SelectedSolution);
                NotifyOfPropertyChange(() => CanActiveSolutionAction);
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is busy.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is busy; otherwise, <c>false</c>.
        /// </value>
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (_isBusy != value)
                {
                    _isBusy = value;
                    NotifyOfPropertyChange(() => IsBusy);
                }
            }
        }

        /// <summary>
        /// Gets or sets the BusyIndicator text.
        /// </summary>
        public string BusyIndicatorText
        {
            get { return _busyIndicatorText; }
            set
            {
                if (_busyIndicatorText != value)
                {
                    _busyIndicatorText = value;
                    NotifyOfPropertyChange(() => BusyIndicatorText);
                }
            }
        }

        #endregion

        #region Guard properties

        /// <summary>
        /// Kontrola, zdali lze aktivovat detail solutionu.
        /// </summary>
        public bool CanActiveSolutionAction { get { return SelectedSolution != null; } }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ShellViewModel"/> class.
        /// </summary>
        [ImportingConstructor]
        public ShellViewModel([ImportMany]IEnumerable<IModule> modules)
        {
            _log.Warn("WARN");

            MenuItems = new BindableCollection<IModule>();

            // lokalizovat!
            DisplayName = "Panel Composer";

            // pridani vsech IModule do seznamu modulu
            Items.AddRange(modules);

            // Pridani viditelnych modulu do menu
            MenuItems.AddRange(modules.Where(s => s.MenuVisible == true).OrderBy(o => o.Order));

            // nastaveni na uvodni obrazovku = "HomeView"
            /// TODO vytahnout do configu?
            this.ActivateItem(modules.First<IModule>(mod => mod.ModuleName == PageNames.Home));

            _log.Info("INFO");
        }

        #endregion

        #region Overrided methods

        /// <summary>
        /// Registrace zpracovani udalosti navigace po strankach do EventAggregatoru.
        /// </summary>
        /// <param name="view"></param>
        protected override void OnViewLoaded(object view)
        {
            // registrace udalosti
            EventAggregator.Subscribe(this);

            // odpalime na vsech modulech metodu reconstruct
            Items.Apply(a => a.OnReconstruct());
        }

        #endregion // Overrided methods

        #region Public methods

        /// <summary>
        /// Actives the solution action.
        /// </summary>
        public void ActiveSolutionAction()
        {
            EventAggregator.Publish(new NavigateEvent(ActiveItem.ModuleName, PageNames.SolutionProjects));
        }

        #endregion

        #region Handle methods

        /// <summary>
        /// Metoda, ktera zpracovava pozadavek na navigaci po strankach.
        /// Zobrazi predanou stranku v parametru.
        /// </summary>
        /// <param name="message"></param>
        public void Handle(NavigateEvent message)
        {
            // vytazeni modulu
            IModule module = Items.First<IModule>(mod => mod.ModuleName == message.PageName);
            // ulozeni referenci na stranku predchudce
            module.SourcePage = message.SourcePage;
            // predani obsahu
            module.Context = message.Context;
            // aktivace stranky
            this.ActivateItem(module);
        }

        /// <summary>
        /// Zpracovani pozadavku na aktivaci solutionu.
        /// </summary>
        /// <param name="message"></param>
        public void Handle(ActiveSolutionEvent message)
        {
            SelectedSolution = (Solution)message.Solution;
        }


        /// <summary>
        /// Metoda, ktera zpracovana pozadavek na zobrazeni BusyIndicatoru.
        /// </summary>
        /// <param name="message"></param>
        public void Handle(BusyEvent message)
        {
            IsBusy = message.IsBusy;
            BusyIndicatorText = message.BusyIndicatorText;
        }

        #endregion 
    }
}
